using WeatherSystem.API.Models;
using WeatherSystem.API.Specifications;

namespace WeatherSystem.API.Repositories
{
    /// <summary>
    /// 用户Repository旧接口适配器
    /// 用于向后兼容新的读写分离架构
    /// </summary>
    public class LegacyUserAdapter : IUserRepository
    {
        private readonly IReadRepository<User> _readRepository;
        private readonly IWriteRepository<User> _writeRepository;

        public LegacyUserAdapter(IReadRepository<User> readRepository, IWriteRepository<User> writeRepository)
        {
            _readRepository = readRepository;
            _writeRepository = writeRepository;
        }

        public async Task<User?> GetByUsernameAsync(string username)
        {
            var spec = new UserSpecification(username);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.FirstOrDefault();
        }

        public async Task<User?> GetByEmailAsync(string email)
        {
            var spec = new UserSpecification(email, true);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.FirstOrDefault();
        }

        public async Task<bool> IsUsernameExistsAsync(string username)
        {
            var spec = new UserSpecification(username);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.Any();
        }

        public async Task<bool> IsEmailExistsAsync(string email)
        {
            var spec = new UserSpecification(email, true);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.Any();
        }

        public async Task<PagedResult<object>> GetUsersPagedAsync(
            int page, int pageSize, string? search = null,
            UserRole? role = null, bool? isActive = null)
        {
            var spec = new UserSpecification(search, role, isActive);
            var result = await _readRepository.GetProjectedPagedAsync(
                u => new { u.Id, u.Username, u.Email, u.Role, u.IsActive, u.CreatedAt, u.LastLoginAt },
                page, pageSize, spec);

            // Convert PagedResult<anonymous type> to PagedResult<object>
            var data = result.Data.Select(d => (object)d).ToList();
            return new PagedResult<object>(data, result.TotalCount, result.Page, result.PageSize);
        }

        public async Task<Dictionary<string, int>> GetUserStatisticsAsync()
        {
            var totalUsers = await _readRepository.CountAsync();
            var activeUsersSpec = new UserSpecification(null, null, true);
            var adminUsersSpec = new UserSpecification(null, UserRole.Admin, null);
            var activeUsers = await _readRepository.CountAsync(activeUsersSpec);
            var adminUsers = await _readRepository.CountAsync(adminUsersSpec);

            return new Dictionary<string, int>
            {
                ["TotalUsers"] = totalUsers,
                ["ActiveUsers"] = activeUsers,
                ["AdminUsers"] = adminUsers,
                ["RegularUsers"] = totalUsers - adminUsers
            };
        }

        public async Task<List<User>> GetActiveUsersAsync()
        {
            var spec = new UserSpecification(null, null, true);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        public async Task<List<User>> GetUsersByRoleAsync(UserRole role)
        {
            var spec = new UserSpecification(null, role, null);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        // 实现基础接口方法
        public async Task<User?> GetByIdAsync(Guid id)
        {
            return await _readRepository.GetByIdAsync(id);
        }

        public async Task<IEnumerable<User>> GetAllAsync()
        {
            var result = await _readRepository.GetAllAsync();
            return result.ToList();
        }

        public async Task<IEnumerable<User>> FindAsync(System.Linq.Expressions.Expression<Func<User, bool>> predicate)
        {
            var spec = new UserSpecification(predicate);
            var result = await _readRepository.GetBySpecificationAsync(spec);
            return result.ToList();
        }

        public async Task AddAsync(User entity)
        {
            await _writeRepository.AddAsync(entity);
        }

        public async Task AddRangeAsync(IEnumerable<User> entities)
        {
            await _writeRepository.AddRangeAsync(entities);
        }

        public async Task UpdateAsync(User entity)
        {
            await _writeRepository.UpdateAsync(entity);
        }

        public async Task UpdateRangeAsync(IEnumerable<User> entities)
        {
            await _writeRepository.UpdateRangeAsync(entities);
        }

        public async Task DeleteAsync(User entity)
        {
            await _writeRepository.DeleteAsync(entity);
        }

        public async Task DeleteRangeAsync(IEnumerable<User> entities)
        {
            await _writeRepository.DeleteRangeAsync(entities);
        }

        public async Task<int> CountAsync(System.Linq.Expressions.Expression<Func<User, bool>>? predicate = null)
        {
            var spec = predicate != null ? new UserSpecification(predicate) : null;
            return await _readRepository.CountAsync(spec);
        }

        // 实现IReadRepository接口的新方法
        public async Task<User?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetByIdAsync(id, cancellationToken);
        }

        public async Task<IEnumerable<User>> GetAllAsync(CancellationToken cancellationToken = default)
        {
            var result = await _readRepository.GetAllAsync(cancellationToken);
            return result.ToList();
        }

        public async Task<IEnumerable<User>> GetBySpecificationAsync(ISpecification<User> specification, CancellationToken cancellationToken = default)
        {
            var result = await _readRepository.GetBySpecificationAsync(specification, cancellationToken);
            return result.ToList();
        }

        public async Task<User?> GetSingleBySpecificationAsync(ISpecification<User> specification, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetSingleBySpecificationAsync(specification, cancellationToken);
        }

        public async Task<int> CountAsync(ISpecification<User>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.CountAsync(specification, cancellationToken);
        }

        public async Task<bool> AnyAsync(ISpecification<User>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.AnyAsync(specification, cancellationToken);
        }

        public async Task<PagedResult<User>> GetPagedAsync(int page, int pageSize, ISpecification<User>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetPagedAsync(page, pageSize, specification, cancellationToken);
        }

        public async Task<IEnumerable<TResult>> GetProjectedAsync<TResult>(System.Linq.Expressions.Expression<Func<User, TResult>> projection, ISpecification<User>? specification = null, CancellationToken cancellationToken = default)
        {
            var result = await _readRepository.GetProjectedAsync(projection, specification, cancellationToken);
            return result.ToList();
        }

        public async Task<PagedResult<TResult>> GetProjectedPagedAsync<TResult>(System.Linq.Expressions.Expression<Func<User, TResult>> projection, int page, int pageSize, ISpecification<User>? specification = null, CancellationToken cancellationToken = default)
        {
            return await _readRepository.GetProjectedPagedAsync(projection, page, pageSize, specification, cancellationToken);
        }

        // 实现IWriteRepository接口的新方法
        public async Task<User> AddAsync(User entity, CancellationToken cancellationToken = default)
        {
            return await _writeRepository.AddAsync(entity, cancellationToken);
        }

        public async Task<IEnumerable<User>> AddRangeAsync(IEnumerable<User> entities, CancellationToken cancellationToken = default)
        {
            var result = await _writeRepository.AddRangeAsync(entities, cancellationToken);
            return result.ToList();
        }

        public async Task UpdateAsync(User entity, CancellationToken cancellationToken = default)
        {
            await _writeRepository.UpdateAsync(entity, cancellationToken);
        }

        public async Task UpdateRangeAsync(IEnumerable<User> entities, CancellationToken cancellationToken = default)
        {
            await _writeRepository.UpdateRangeAsync(entities, cancellationToken);
        }

        public async Task DeleteAsync(User entity, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteAsync(entity, cancellationToken);
        }

        public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteAsync(id, cancellationToken);
        }

        public async Task DeleteRangeAsync(IEnumerable<User> entities, CancellationToken cancellationToken = default)
        {
            await _writeRepository.DeleteRangeAsync(entities, cancellationToken);
        }

        public async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            return await _writeRepository.SaveChangesAsync(cancellationToken);
        }
    }
}